package com.zwy.game2048;

import java.util.*;

public class Game {
    private List<Integer> emptyLocation=new ArrayList<>();
    private int randomNum=0;
    private int [][]blocks=new int[4][4];
    private  int max=0;
    private int score=0;
    public void init(){

        int index=0;
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                blocks[i][j]=0;
                emptyLocation.add(index);
                index++;
            }
        }
        random();
        random();
    }
    public void random(){
        double d=Math.random()*(emptyLocation.size()-1);
        randomNum=(int)d;
        Integer integer = emptyLocation.get(randomNum);
        blocks[integer/4][integer%4]=Math.random()>0.1?2:4;
        fun();
    }
    public void fun(){
        emptyLocation.clear();
        for (int i = 0; i < blocks.length; i++) {
            for (int j = 0; j < blocks[0].length; j++) {
                if(blocks[i][j]==0)emptyLocation.add(i*4+j);
            }
        }
    }
    public boolean canUp(){
        int zeroCount=0;
        int [][]arr=blocks.clone();
            for (int i = 0; i < 4; i++) {
                zeroCount=0;
                if(blocks[0][i]==0)zeroCount++;
                for (int j = 1; j < 4; j++) {
                    if(arr[j][i]==0)zeroCount++;
                    else if(j-zeroCount-1>=0&&arr[j][i]==arr[j-zeroCount-1][i]){
                       return true;
                    }
                    else {
                        if(zeroCount>0){
                           return true;
                        }
                    }
                }
            }
            return false;
            }
        public boolean canDown(){
            int zeroCount=0;
            int [][]arr=blocks.clone();
                for (int i = 0; i < 4; i++) {
                    zeroCount=0;
                    if(arr[3][i]==0)zeroCount++;
                    for (int j = 2; j >= 0; j--) {
                        if(arr[j][i]==0)zeroCount++;
                        else if(j+zeroCount+1<=3&&arr[j][i]==arr[j+zeroCount+1][i]){
                           return true;
                        }
                        else {
                            if(zeroCount>0) {
                                return true;
                            }
                        }
                    }
                }
            return false;
        }
        public boolean canLeft(){
            int zeroCount=0;
            int [][]arr=blocks.clone();
                for (int i = 0; i < 4; i++) {
                    zeroCount=0;
                    if(arr[i][0]==0)zeroCount++;
                    for (int j = 1; j < 4; j++) {
                        if(arr[i][j]==0)zeroCount++;
                        else if(j-zeroCount-1>=0&&arr[i][j]==arr[i][j-zeroCount-1]){
                            return true;
                        }
                        else {
                            if(zeroCount>0) {
                               return true;
                            }
                        }
                    }
                }
          return false;
        }
    public boolean canRight(){
        int zeroCount=0;
        int [][]arr=blocks.clone();
            for (int i = 0; i < 4; i++) {
                zeroCount=0;
                if(arr[i][3]==0)zeroCount++;
                for (int j = 2; j >= 0; j--) {
                    if(arr[i][j]==0)zeroCount++;
                    else if(j+zeroCount+1<=3&&arr[i][j]==arr[i][j+zeroCount+1]){
                       return true;
                    }
                    else {
                        if(zeroCount>0) {
                           return true;
                        }
                    }
                }
            }
        return false;
    }
    public void moveUp(){
        int zeroCount=0;//记录前面0的个数
           for (int i = 0; i < 4; i++) {
               zeroCount=0;
               if(blocks[0][i]==0)zeroCount++;//判断第0行是否有0
               for (int j = 1; j < 4; j++) {
                   if(blocks[j][i]==0)zeroCount++;//如果是0
                   else if(j-zeroCount-1>=0&&blocks[j][i]==blocks[j-zeroCount-1][i]){
                       //如果上一个数与现在相等 则合并
                       score+= blocks[j-zeroCount-1][i];
                       blocks[j-zeroCount-1][i]*=2;

                       //记录最大值
                       max=Math.max(max, blocks[j-zeroCount-1][i]);
                       blocks[j][i]=0;
                       zeroCount++;

                   }
                   else {
                       if(zeroCount>0){
                           //如果前面有0
                           blocks[j-zeroCount][i]=blocks[j][i];
                           blocks[j][i]=0;
                       }
                   }
               }
           }
    }
    public void moveDown(){
        int zeroCount=0;
            for (int i = 0; i < 4; i++) {
                zeroCount=0;
                if(blocks[3][i]==0)zeroCount++;
                for (int j = 2; j >= 0; j--) {
                    if(blocks[j][i]==0)zeroCount++;
                    else if(j+zeroCount+1<=3&&blocks[j][i]==blocks[j+zeroCount+1][i]){
                        score+= blocks[j-zeroCount-1][i];
                        blocks[j+zeroCount+1][i]*=2;
                        max=Math.max(max,  blocks[j+zeroCount+1][i]);
                        blocks[j][i]=0;
                        zeroCount++;

                    }
                    else {
                        if(zeroCount>0){
                            blocks[j+zeroCount][i]=blocks[j][i];
                            blocks[j][i]=0;
                        }
                    }
                }
            }
    }
    public void moveLeft(){
        int zeroCount=0;
            for (int i = 0; i < 4; i++) {
                zeroCount=0;
                if(blocks[i][0]==0)zeroCount++;
                for (int j = 1; j < 4; j++) {
                    if(blocks[i][j]==0)zeroCount++;
                    else if(j-zeroCount-1>=0&&blocks[i][j]==blocks[i][j-zeroCount-1]){
                        score+= blocks[j-zeroCount-1][i];
                        blocks[i][j-zeroCount-1]*=2;
                        max=Math.max(max, blocks[i][j-zeroCount-1]);
                        blocks[i][j]=0;
                        zeroCount++;

                    }
                    else {
                        if(zeroCount>0) {
                            blocks[i][j - zeroCount] = blocks[i][j];
                            blocks[i][j] = 0;

                        }
                    }
                }
            }
    }
    public void moveRight(){
        int zeroCount=0;
            for (int i = 0; i < 4; i++) {
                zeroCount=0;
                if(blocks[i][3]==0)zeroCount++;
                for (int j = 2; j >= 0; j--) {
                    if(blocks[i][j]==0)zeroCount++;
                    else if(j+zeroCount+1<=3&&blocks[i][j]==blocks[i][j+zeroCount+1]){
                        score+= blocks[j-zeroCount-1][i];
                        blocks[i][j+zeroCount+1]*=2;
                        max=Math.max(max, blocks[i][j+zeroCount+1]);
                        blocks[i][j]=0;
                        zeroCount++;

                    }
                    else {
                        if(zeroCount>0) {
                            blocks[i][j + zeroCount] = blocks[i][j];
                            blocks[i][j] = 0;
                        }
                    }
                }
            }
    }
    public void move(int d){
        switch (d){
            case 1: if(canUp()){
                moveUp();
                fun();random();
            }
                break;
            case 2:
                if(canDown()){
                    moveDown();fun();random();
                }
               break;
            case 3:
                if(canLeft()){
                    moveLeft();fun();random();
                }
               break;
            case 4:
                if(canRight()){
                    moveRight();fun();random();
                }
                break;
        }
    }
    public void draw(){
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                if(blocks[i][j]==0) System.out.print(0+" ");
                else System.out.print(blocks[i][j]+" ");
            }
            System.out.println();
        }
    }
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        Game game=new Game();
        FileCSVTest csvUtils=new FileCSVTest();
        List<List<Integer>> listList=new ArrayList<List<Integer>>();
        List<Integer> list=null;
        game.init();
        int next=0;
        int getScore=0;
//        game.blocks[0][0]=4;
//        game.blocks[0][1]=16;
//        game.blocks[0][2]=4;
//        game.blocks[0][3]=0;
//        game.blocks[1][0]=4;
//        game.blocks[1][1]=0;
//        game.blocks[1][2]=0;
//        game.blocks[1][3]=0;
//        game.blocks[2][0]=2;
//        game.blocks[2][1]=16;
//        game.blocks[2][2]=0;
//        game.blocks[2][3]=0;
//        game.blocks[3][0]=2;
//        game.blocks[3][1]=2;
//        game.blocks[3][2]=0;
//        game.blocks[3][3]=0;
        while(true){
            game.draw();
            System.out.print("请输入： ");
             next = scanner.nextInt();
            list=new ArrayList<Integer>();
            for (int i = 0; i < 4; i++) {
                for (int j = 0; j < 4; j++) {
                    list.add(game.blocks[i][j]);
                }
            }
            getScore=game.score;
            list.add(next);
            System.out.println();
             game.move(next);
             if(game.max==2048)break;
             list.add(game.score-getScore);
             listList.add(list);
             
        }
        System.out.println("bingo");
    }
}
